import { t } from '@src/locales'
import ExecuteCodeClass from '@src/component/form/components/FormJsControl/model/executeCode';
import {
    ButtonSetDetailForButtonStyleTypeEnum,
    ButtonSetDetailForShowPositionEnum,
    ButtonSetDetailForButtonConcatEventEnum,
    ButtonSetDetailModuleEnum,
    ButtonGetTriggerModuleEnum,
} from 'pub-bbx-global/pageType/dist/enum/ButtonSetEnum'
import { isEmpty } from 'pub-bbx-utils'
import { cloneDeep } from 'lodash'
import { getDataForButtonSet } from '@src/api/SystemApi'
import platform from '@src/platform';
import { message } from '@src/util/message'
import { manualTrigger } from '@src/modules/connector/api/trigger'
import { isObject } from 'pub-bbx-utils'
import { LINK_REG } from '@src/util/validator'
import Platform from '@src/util/platform'
// 最多添加的按钮数量
export const normalBtnMixNumber = 5

export const buttonPrimaryKey = 'primaryKey'

// 按钮基础配置项
export const useStateForButtonSetDetailSetConfig = () => {
    const createTypeChooseItem = (label: string, value: ButtonSetDetailForButtonStyleTypeEnum) => {
        return {
            label,
            value
        }
    }
    const typeColorEnum = {
        [ButtonSetDetailForButtonStyleTypeEnum.Primary]: 'type-primary',
        [ButtonSetDetailForButtonStyleTypeEnum.Gray]: 'type-gray',
    }
    const typeChooseArr = [
        createTypeChooseItem(t('setting.buttonSet.text6'), ButtonSetDetailForButtonStyleTypeEnum.Primary),
        createTypeChooseItem(t('setting.buttonSet.text7'), ButtonSetDetailForButtonStyleTypeEnum.Gray)
    ]

    const createShowPositionChooseItem = (label: string, value: ButtonSetDetailForShowPositionEnum, des: string) => {
        return {
            label,
            value,
            des,
            disabled:value === ButtonSetDetailForShowPositionEnum.PcDetail
        }
    }

    const showPositionChooseArr = [
        createShowPositionChooseItem(t('setting.buttonSet.text8'), ButtonSetDetailForShowPositionEnum.PcList, ''),
        createShowPositionChooseItem(t('setting.buttonSet.text9'), ButtonSetDetailForShowPositionEnum.PcDetail, ''),
        createShowPositionChooseItem(t('setting.buttonSet.text10'), ButtonSetDetailForShowPositionEnum.MobileDetail, ''),
    ]


    // 设置数据的校验方法
    const validateForButtonSet = async (btnList: any) => {
        let result: any = { pass: true }
        try {
            for (let index = 0; index < btnList.length; index++) {
                const item = btnList[index];
                // 校验名称
                if (isEmpty(item.name) || item.name.trim().length === 0) {
                    result = {
                        pass: false,
                        pathId: item.pathId,
                        errorModule: ButtonSetDetailModuleEnum.Base,
                    }
                    break
                }
                // 校验是否绑定触发器
                const trigger = item.event.find((i: any) => i.type === ButtonSetDetailForButtonConcatEventEnum.Trigger);
                if (trigger?.execute?.length === 0) {
                    result = {
                        pass: false,
                        pathId: item.pathId,
                        errorModule: ButtonSetDetailModuleEnum.Event,
                    }
                    break
                }
                // 校验是否绑定正确的链接和是否绑定任务类型
                const linker = item.event.find((i: any) => i.type === ButtonSetDetailForButtonConcatEventEnum.Linker);       
                if (linker && (linker?.execute?.length === 0 || !LINK_REG.test(linker?.execute[0])) || !item.event[0]?.type) {
                    result = {
                        pass: false,
                        pathId: item.pathId,
                        errorModule: ButtonSetDetailModuleEnum.Event,
                    }
                    break
                }
            }
        } catch (error) {
            console.error(error, '<-----validateForButtonSet is Error')
            return Promise.resolve({ pass: false, })
        }

        return Promise.resolve(result)
    }

    return {
        typeChooseArr,
        showPositionChooseArr,
        typeColorEnum,
        validateForButtonSet,
    }
}

/**
 * @des 获取不同模块调用获取触发器的列表接口的参数
 */
export const getHttpParamsForButtonSetTriggerList = (mode: ButtonGetTriggerModuleEnum) => {
    const enumObj = {
        [ButtonGetTriggerModuleEnum.Customer]: [{
            bizType: ButtonGetTriggerModuleEnum.Customer,
            bizTypeId: 1
        }, {
            bizType: 'CUSTOMER_ADDITIONAL',
            bizTypeId: 1
        }],
        [ButtonGetTriggerModuleEnum.Product]: [{
            bizType: ButtonGetTriggerModuleEnum.Product,
            bizTypeId: 2
        },
        {
            bizType: 'PRODUCT_ADDITIONAL',
            bizTypeId: 2
        }]
    }
    return enumObj[mode]
}

/**
 * @des 将接口数据转换为本地所需要的数据
 */
export const packToLocalByHttpDataForButonList = (btnList: any) => {
    let arr = cloneDeep(btnList)
    return arr.map((i: any, index: number) => {
        const { buttonId, show } = i
        if (buttonId) {
            i['pathId'] = [buttonId]
            i[buttonPrimaryKey] = buttonId
        } else {
            console.error(`${index} buttonId is Miss`)
        }
        let position = []
        if (show.detail) {
            position.push(ButtonSetDetailForShowPositionEnum.PcDetail)
        }
        if (show.list) {
            position.push(ButtonSetDetailForShowPositionEnum.PcList)
        }
        if (show.mobile) {
            position.push(ButtonSetDetailForShowPositionEnum.MobileDetail)
        }
        i['position'] = position
        i.event?.map((item: any) => {
            if (!item.execute) item.execute = [];
            return item;
        })      
        return i

    })

}

/**
 * @des 将本地数据转换为接口所需要的数据
 */
export const packToHttpByHttpDataForButonList = (btnList: any) => {
    let arr = cloneDeep(btnList)
    return arr.map((i: any) => {
        const { position } = i
        delete i[buttonPrimaryKey]
        delete i['pathId']
        i['show'] = {
            mobile: !!position?.includes(ButtonSetDetailForShowPositionEnum.MobileDetail),
            detail: !!position?.includes(ButtonSetDetailForShowPositionEnum.PcDetail),
            list: !!position?.includes(ButtonSetDetailForShowPositionEnum.PcList),
        }
        delete i['position']
        return i
    })
}

/**
 * @des 获取详情的页面按钮
 */
export const getPageButtonListForView = (mode: ButtonGetTriggerModuleEnum, pageMode:ButtonSetDetailForShowPositionEnum, params: any = {}, returnFnc: any = null) => {
    const paramsEnum = {
        [ButtonGetTriggerModuleEnum.Customer]: {
            module: ButtonGetTriggerModuleEnum.Customer,
            moduleId: 1,
            isEdit: false,
        },
        [ButtonGetTriggerModuleEnum.Product]: {
            module: ButtonGetTriggerModuleEnum.Product,
            moduleId: 2,
            isEdit: false,
        }
    }
    const filterEnum = {
        [ButtonSetDetailForShowPositionEnum.MobileDetail]:'mobile',
        [ButtonSetDetailForShowPositionEnum.PcDetail]:'detail',
        [ButtonSetDetailForShowPositionEnum.PcList]:'list',
    }
    if (!paramsEnum[mode]) {
        return console.error('mode is Miss')
    }
    const params_ = {
        ...paramsEnum[mode],
        ...params,
    }
    return getDataForButtonSet(params_).then(res => {
        if (res.status === 0) {
            const arr = res.data.filter((i: any) => {
                return filterEnum[pageMode] && i.show?.[filterEnum[pageMode]] === true
            })
            returnFnc && returnFnc(arr)
        } else {
            platform.notification({
                type: 'error',
                title: t('common.base.fail'),
                message: res.message,
            });
        }
    })
}

/**
 * @des 自定义按钮的点击事件
 * @param multipleSelection 选中的数据
 * @param params 代码块需要的自定义参数
 */
export const pageButtonClick = async(item: any, multipleSelection: any = null, params: any = {}, before: any = null, success: any = null, final: any = null) => {
    const { event=[] } = item
    // 自定义链接
    const linker = event.find((i: any) => i.type === ButtonSetDetailForButtonConcatEventEnum.Linker)
    if(linker) {
        let fromId = window.frameElement?.getAttribute('id') as string;
        let url = `${event[0]?.execute?.[0]}`;
        if(!url) return;

        Platform.openTab({
          title: `${item.name}`,
          url,
          close: true,
          fromId,
          id: `${item.buttonId}`
        })
        return;
    }
    if (multipleSelection?.length === 0) {
        return platform.alert(t('common.modal.PLEASE_SELECT_DATA_MESSAGE'))
    }
    // 代码块
    const code = event.find((i: any) => i.type === ButtonSetDetailForButtonConcatEventEnum.Code);
    if (code) {
        before && before();
        const jsCode = await executeCode(event[0].codeContent, multipleSelection, {...params});
        final && final();
        const key = "errorMessage";
        if (jsCode) {
            const obj = JSON.parse(jsCode as string);
            if (obj.hasOwnProperty(key)) {
                return message.warning(obj[key]);
            }
        }
        return;
    }
    // 触发器
    const trigger = event.find((i: any) => i.type === ButtonSetDetailForButtonConcatEventEnum.Trigger);
    let bizIdList = []
    if (multipleSelection.length > 0) {
        bizIdList = multipleSelection.map((i: any) => {
            if (isObject(i)) {
                return i.id
            } else {
                return i
            }
        })
    }
    before && before()
    manualTrigger({
        triggerId: trigger.execute.join('，'),
        bizIdList
    }).then(res => {
        const isSucc = res.status === 0
        platform.notification({
            type: isSucc ? 'success' : 'error',
            title: isSucc ? t('common.base.tip.operationSuccess') : t('common.base.tip.operationFail'),
            message: !isSucc && res.message
        })
        success && success()
    }).finally(() => {
        final && final()
    })
}

/* 解析js代码块 */
export async function executeCode(code: string, multipleSelection: any, config: any = {}) {
    const executeCodeClassInstance =  ExecuteCodeClass.getInstance({...config});
    return await executeCodeClassInstance.executeCodeForListAndDetail(code, multipleSelection, config);
}